home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 05 / 6 / DISK0564.ZIP / SOURCE.ARC / RM.ASM < prev    next >
Assembly Source File  |  1989-02-04  |  21KB  |  617 lines

  1.         TITLE RM - MSDOS FILE DELETE UTILITY
  2.         PAGE 55,132
  3. ;**********************************************************************
  4. ;       THIS PROGRAM DELETES ONE OR MORE FILES, OR (WITH THE /R SWITCH)
  5. ;    DIRECTORIES.
  6. ;
  7. ;       USAGE (afn = ambiguous file name):
  8. ;
  9. ;               RM afn1 afn2 ...  - deletes the named file(s)
  10. ;
  11. ;       SWITCHES (OPTIONAL):
  12. ;
  13. ;        RM/F - remove write-protected files without warning
  14. ;
  15. ;        RM/I - query before each deletion
  16. ;
  17. ;               RM/R - allows deleting directories (recursively).
  18. ;               (this is DANGEROUS, especially without the /I switch)
  19. ;
  20. ;               RM/V - "verbose" mode, shows name of each file deleted.
  21. ;************************************************************************
  22. ;       BY: JON DART
  23. ;           3012 HAWTHORN ST.,
  24. ;           SAN DIEGO, CA 92104
  25. ;************************************************************************
  26. ;   TO BUILD RM.EXE:
  27. ;    MASM RM,RM,NUL,NUL
  28. ;    LINK RM,RM,NUL,ASM
  29. ;    EXEPACK RM.EXE RM2.EXE
  30. ;    DEL RM.EXE
  31. ;    REN RM2.EXE=RM.EXE
  32. ;************************************************************************
  33. ;       Version 3.2, 04-Feb-89  fixes to CHECKWILD
  34. ;    Version 3.1, 19-Jan-89  another fix to FIXPATH; relinked.
  35. ;    Version 3.0, 24-Sep-88  bug fix in FIXPATH; relinked. Version made
  36. ;                consistent with MV and CP.
  37. ;    Version 1.6, 16-Feb-88  assembles under MASM 5.0, uses GETARGS
  38. ;                for argument processing.
  39. ;    Version 1.5, 24-Oct-86  switch parser modified, recognizes -rv
  40. ;                form as well as -r -v
  41. ;    Version 1.4, 10-Sep-86  (fixes prompt for write-protected files)
  42. ;    Version 1.3, 19-Jul-86  (fixes gross bugs in wildcard handling)
  43. ;    Version 1.2, 06-Jul-86  (changes to memory alloc., accepts hyphen
  44. ;                 as switch char., assembles under masm 4.0)
  45. ;    Version 1.1, 03-Jul-86  (bug fixes)
  46. ;       Version 1.0, 30-Jun-86
  47. ;************************************************************************
  48.  
  49.     DOSSEG
  50.     .MODEL    SMALL
  51.  
  52. PATHSIZE EQU    65                      ;MAX. SIZE OF DOS PATHNAME, +1
  53. MAXLEVEL EQU    12                      ;MAX NESTING LEVEL FOR DIRECTORIES
  54. MAXARGS EQU     40                      ;MAXIMUM # OF COMMAND LINE ARGUMENTS
  55. FALSE   EQU     0
  56. TRUE    EQU     0FFH
  57. CONFIRM EQU     FALSE                   ;"CONFIRM BEFORE DELETE" DEFAULT
  58. VERBOSE EQU     FALSE                   ;"VERBOSE" OPTION (DEFAULT VALUE)
  59. GOOFPROOF EQU    TRUE            ;CONFIRM BEFORE DELETING *.*
  60. BIT$DIR EQU     00010000B               ;BIT IN ATTRIBUTE FOR DIRECTORY
  61. BIT$RO  EQU     00000001B               ;BIT IN ATTRIBUTE FOR WRITE-PROTECT
  62.  
  63.         .XLIST
  64.         INCLUDE ASCII.DEF
  65.         INCLUDE MSDOS2.DEF
  66.     INCLUDE MACROS.DEF
  67.         .LIST
  68.  
  69. RMINFO  STRUC
  70. NEWDIR  DW      1 DUP (?)               ;FLAG, =1 IF NEW DIRECTORY CREATED
  71. PATHTYPE DB     2 DUP (?)               ;TYPE OF SOURCE (0 IF UFN)
  72. ARG     DB      PATHSIZE DUP (?)        ;FIRST ARGUMENT (SOURCE)
  73. SPATH   DB      PATHSIZE DUP (?)        ;SOURCE SEARCH PATH
  74. SPREFIX DB      PATHSIZE DUP (?)        ;SOURCE LEAD-IN PATH
  75. SCRATCH DB      PATHSIZE DUP (?)        ;SCRATCH AREA
  76. FULLNAME DB     PATHSIZE DUP (?)        ;UNAMBIGUOUS SOURCE NAME
  77. DTA     DB      128 DUP (?)             ;DTA FOR SEARCH FN.
  78. RMINFO  ENDS
  79. RMSTRUCSIZE EQU 5*PATHSIZE+135          ;SIZE OF STRUCTURE
  80.  
  81.     .DATA
  82. ;
  83. ;       FIXED DATA AREA:
  84. ;
  85. MSG1    DB 'RM Version 3.2 by Jon Dart (04-Feb-89)',CR,LF,CR,LF
  86.         DB 'USAGE:',CR,LF,CR,LF
  87.         DB 'RM [-F -I -R -V] file1 file2  ...      deletes the named file(s)',CR,LF,CR,LF
  88.         DB 'SWITCHES (OPTIONAL):',CR,LF,CR,LF
  89.     DB '-F   remove write-protected files without warning',CR,LF
  90.     DB CR,LF
  91.         DB '-I   query before delete',CR,LF
  92.         DB CR,LF
  93.         DB '-R   allow recursive deletion of directories',CR,LF
  94.     DB CR,LF
  95.     DB '-V   echo file names as they are deleted',CR,LF
  96.         DB 0
  97. MSG2    DB      ': file not found.',CR,LF,0
  98. MSG3    DB      ': directory.',CR,LF,0
  99. MSG4    DB      ' : OK to delete [Y or N]? ',0
  100. MSG5    DB      ": can't remove.",CR,LF,0
  101. MSG6    DB      ': file is R/O. '
  102. MSG6A    DB    'Are you SURE [Y or N]? ',0
  103. MSG7    DB      "Directories nested too deep.",CR,LF,0
  104. ; MSG8    DB      "Insufficient memory for buffers.",CR,LF,0
  105. MSG9    DB      ": Illegal switch.",CR,LF,0
  106. MSG10   DB      "Too many arguments.",CR,LF,0
  107. MSG11    DB    ' directory. Enter it [Y or N]? ',0
  108. MSG12    DB    ' directory. Delete it [Y or N]? ',0
  109. MSG13    DB    '? ',0
  110. WILD    DB    '*.*',0
  111. SWLIST  DB    'FIRV',0        ;LIST OF LEGAL SWITCHES
  112.  
  113.     .STACK
  114.         DB      512 DUP (?)
  115.  
  116.     .DATA?
  117. ;    UNINITIALIZED DATA AND BUFFER AREAS       
  118.  
  119. RBASE   DW     1 DUP (?)               ;POINTER TO MVSTRUC IN RSTACK
  120. LEVEL   DW      1 DUP (?)               ;RECURSION LEVEL
  121. DRIVE   DW      1 DUP (?)               ;SOURCE DRIVE (0 = DEFAULT)
  122. FFLAG   DW    1 DUP (?)               ;FORCE FLAG
  123. IFLAG    DW    1 DUP (?)        ;CONFIRM FLAG
  124. RFLAG   DW    1 DUP (?)               ;RECURSIVE FLAG
  125. VFLAG   DW    1 DUP (?)               ;VERBOSE FLAG
  126. FNAME_START DW  1 DUP (?)               ;USED BY CHECKWILD
  127. NUMARGS DW      1 DUP (?)               ;NUMBER OF ARGUMENTS ON COMMAND LINE
  128. ARGPTRS DW      MAXARGS DUP (?)         ;POINTERS TO START OF ARGUMENTS
  129. ARGBUF  DB      256 DUP (?)        ;BUFFER FOR ARGUMENTS
  130. RSTACK  RMINFO  MAXLEVEL DUP (<>)    ;RECURSION STACK
  131.  
  132.         PAGE +
  133.     .CODE
  134. EXTRN   CPYCNT:NEAR,UC:NEAR,UCSTR:NEAR,CRLF:NEAR
  135. EXTRN   ERRORMSG:NEAR,COUT:NEAR,CIN:NEAR,CLRCO:NEAR
  136. EXTRN   SKIPSP:NEAR,TYPTX:NEAR,ERRORMSG:NEAR,CLRCO:NEAR
  137. EXTRN   CMDSRC:NEAR,FIXPATH:NEAR,TYPE_DIR:ABS,TYPE_AFN:ABS
  138. EXTRN   TYPE_UFN:ABS,TYPE_DSP:ABS,TYPE_DRV:ABS,TYPE_UNK:ABS
  139. EXTRN    GETYORN:NEAR
  140. EXTRN    GETARGS:NEAR
  141.  
  142. ;*********************
  143. ;* MACRO DEFINITIONS *
  144. ;*********************
  145.  
  146. ADDR    MACRO   REG,OFFST               ;COMPUTE ADDRESS OFFSET FROM BASE REGISTER (BX)
  147.         MOV     REG,BX
  148.         ADD     REG,OFFST
  149.         ENDM
  150.  
  151. COPYPATH MACRO  SOURCE,DEST             ;COPY PATHNAME FROM SOURCE TO DEST
  152.         ADDR    SI,SOURCE
  153.         ADDR    DI,DEST
  154.         MOV     CX,PATHSIZE
  155.         CALL    CPYCNT
  156.         ENDM
  157.  
  158. ERROR   MACRO   ERRNUM                  ;SHOW ERROR MESSAGE
  159.         PUSH    DS
  160.         MOV     AX,DGROUP 
  161.         MOV     DS,AX
  162.         MOV     DX,OFFSET MSG&ERRNUM
  163.         CALL    ERRORMSG
  164.         POP     DS
  165.         ENDM
  166.  
  167. ;**********************
  168. ; PROGRAM ENTRY POINT *
  169. ;**********************
  170. ENTRY:
  171.         TEST_DOS2                       ;TEST FOR DOS 2.0, EXIT IF DOS 1
  172.     MOV    AX,DGROUP
  173.     MOV    ES,AX
  174.         MOV     BX,(80H)             ;GET BYTE COUNT FOR COMMAND LINE
  175.         CMP     [BX],BYTE PTR 0
  176.         JE      USEMSG                  ;IF NO COMMAND TAIL
  177.         PUSH    BX
  178.         MOV     DL,[BX]
  179.         MOV     DH,0
  180.         ADD     BX,DX
  181.         INC     BX
  182.         MOV     [BX],BYTE PTR 0         ;PUT 0 BYTE AT END OF COMMAND LINE
  183.         POP     BX
  184.         INC     BX
  185.     MOV    SI,OFFSET ARGPTRS
  186.     MOV    DI,OFFSET ARGBUF
  187.     MOV    CX,MAXARGS
  188.     CALL    GETARGS            ;COLLECT COMMAND LINE ARGUMENTS
  189.     JNB    L_2            ;IF OK
  190. TOOMANY:
  191.         ERROR   10                      ;TOO MANY ARGUMENTS (PRETTY UNLIKELY)
  192.     MOV    AL,10            ;SET EXIT CODE
  193.         JMP     EXIT2
  194. L_2:    CMP     CX,0
  195.     JG    L_3            ;IF AT LEAST 1 ARG
  196. USEMSG: ERROR   1            ;NO ARGUMENTS, SHOW CORRECT USAGE
  197.     MOV    AL,1            ;SET ERROR CODE
  198.         JMP     EXIT2            ;EXIT 2 DOS
  199. L_3:
  200.         MOV     AX,ES
  201.         MOV     DS,AX                   ;SET DATA SEG TO VARIABLE AREA
  202.         MOV     BYTE PTR IFLAG,CONFIRM  ;SET CONFIRM FLAG DEFAULT
  203.         MOV     BYTE PTR VFLAG,VERBOSE  ;SET VERBOSE FLAG DEFAULT
  204.     MOV    BYTE PTR RFLAG,FALSE    ;SET RECURSIVE FLAG DEFAULT
  205.     MOV    BYTE PTR FFLAG,FALSE    ;SET FORCE FLAG DEFAULT
  206.     MOV    WORD PTR LEVEL,0    ;ZERO RECURSION LEVEL
  207.         MOV     BYTE PTR DRIVE,0         ;SET DRIVE DEFAULT
  208. ;***************************
  209. ; COLLECT SWITCHES, IF ANY *
  210. ;***************************
  211.     MOV    SI,OFFSET ARGPTRS
  212. NEXTSW:
  213.     MOV    BX,WORD PTR [SI]    ;POINT TO ARGUMENT
  214.     MOV    AL,BYTE PTR [BX]    ;GET 1ST CHAR.
  215.         CMP     AL,'-'
  216.         JE      GOTSW                   ;IF SWITCH SPECIFIED
  217.     CMP    AL,'/'
  218.     JE     GOTSW
  219.     JMP    GETFILES
  220. GOTSW:
  221.         INC     BX                      ;SKIP OVER SWITCH CHARACTER
  222.     MOV    AL,BYTE PTR [BX]
  223. SWLOOP:
  224.         CALL    UC                      ;MAKE SWITCH UPPER CASE
  225.     PUSH    BX
  226.     MOV    BX,OFFSET SWLIST
  227.     CALL    CMDSRC            ;SEARCH LIST OF VALID SWITCHES
  228.     POP    BX
  229.     MOV    AH,0
  230.     ADD    AX,AX            ;NOT FOUND IN LIST?
  231.     JZ    BADSWITCH        ;NO.
  232.     MOV    DI,OFFSET FFLAG - 2
  233.     ADD    DI,AX            ;POINT TO FLAG
  234.     NOT    WORD PTR [DI]        ;1'S COMPLEMENT
  235.     INC    BX
  236.     MOV    AL,BYTE PTR [BX]    ;GET NEXT CHAR. FROM LINE
  237.     COMPLIST <SPACE,TAB,NULL>,ENDSW ;IF DELIM
  238.     JMP    SWLOOP            ;ELSE ASSUME THIS IS A SWITCH CHAR.
  239. ENDSW:    ADD    SI,2            ;POINT TO NEXT POINTER TO AN ARG
  240.     LOOP    NEXTSW
  241.     ERROR    1            ;NO ARGS BESIDES SWITCHES
  242.     MOV    AL,1
  243.     JMP    EXIT2    
  244. BADSWITCH:
  245.     MOV    AL,BYTE PTR [BX]
  246.         CALL    COUT                    ;DISPLAY BAD CHAR.
  247.         ERROR   9                       ;ILLEGAL SWITCH
  248.     MOV    AL,9            ;SET EXIT CODE
  249.         JMP     EXIT2
  250. GETFILES:
  251.         CMP     CX,0                    ;CHECK ARGUMENT COUNT
  252.         JG      ARGSOK                  ;IF AT LEAST 1
  253. NOARGS:
  254.         JMP     USEMSG                  ;GIVE USE MESSAGE
  255. ARGSOK: MOV     WORD PTR NUMARGS,CX      ;SAVE NUMBER OF ARGUMENTS (LESS SWITCHES)
  256.  
  257. ;*****************************************
  258. ;* LOOP, DELETING FILES IN ARGUMENT LIST *
  259. ;*****************************************
  260. RM1ARG:
  261.         MOV     BX, WORD PTR [SI]       ;GET POINTER TO ARG
  262.         PUSH    SI
  263.         PUSH    CX
  264.         CALL    RMARG                   ;DELETE IT
  265.         POP     CX
  266.         POP     SI
  267.         ADD     SI,2                    ;ADVANCE TO NEXT ARG POINTER
  268.         LOOP    RM1ARG                  ;LOOP TILL NO MORE ARGS TO DELETE
  269.     MOV    AL,0            ;SET EXIT CODE
  270.         JMP     EXIT2
  271.  
  272. ;*******************
  273. ;* REMOVE ONE FILE *
  274. ;*******************
  275. RMARG   PROC   NEAR
  276.         MOV     BYTE PTR DRIVE,0         ;SET DRIVE DEFAULT
  277.         MOV     DI,OFFSET RSTACK+ARG    ;COLLECT FILE NAME
  278.         MOV     AL,[BX+1]
  279.         CMP     AL,':'                  ;CHECK FOR DRIVE SPEC
  280.         JNE     GETARG            ;IF NONE
  281.         MOV     AL,[BX]                 ;GET DRIVE LETTER
  282.         SUB     AL,'A'-1                ;MAKE BINARY
  283.         MOV     BYTE PTR DRIVE,AL        ;SAVE DRIVE
  284. GETARG: MOV     AL,[BX]                 ;COPY FROM [BX] TO [DI] UNTIL DELIMITER
  285.     CMP    AL,0
  286.     JE    ENDARG
  287.         STOSB
  288.         INC     BX
  289.         JMP     GETARG
  290. ENDARG: 
  291.         STOSB                           ;END ARG W. ZERO
  292.         MOV     WORD PTR RBASE,OFFSET RSTACK   ;SAVE OFFSET TO RSTACK
  293.         CALL    RMIT                    ;DO IT TO IT
  294.         RET
  295. RMARG   ENDP
  296.  
  297.         PAGE +
  298. ;*********************************************************************
  299. ; THIS ROUTINE REMOVES A FILE OR DIRECTORY WHOSE PATHNAME IS SPECIFIED
  300. ; IN FIELD 'ARG' OF A STRUCTURE OF TYPE 'RMSTRUC'.  'RBASE' POINTS
  301. ; TO THE START OF THE DATA STRUCTURE FOR THIS RECURSION LEVEL.
  302. ;
  303. RMIT    PROC    NEAR
  304.         MOV     BX,WORD PTR RBASE        ;GET BASE ADDR. (POINTER TO RMINFO)
  305.         ADDR    DX,DTA
  306.         MOV     AH,SET_DTA
  307.         INT     DOS                     ;SET DTA
  308.         ADDR    CX,SPATH
  309.         ADDR    DX,SPREFIX
  310.         PUSH    BX
  311.         ADD     BX,ARG
  312.         CALL    FIXPATH                 ;PARSE PATHNAME
  313.         POP     BX
  314.         CMP     AX,TYPE_UNK
  315.         JNE     GOODPATH                ;IF APPARENTLY OK
  316.         ADDR    DX,ARG
  317.         CALL    ERRORMSG
  318.         ERROR   2                       ;NONEXISTENT PATHNAME, COMPLAIN
  319.         RET
  320. GOODPATH:
  321.         MOV     WORD PTR [BX].PATHTYPE,AX     ;SAVE TYPE OF ARGUMENT
  322.     IF    GOOFPROOF
  323.     CMP    AX,TYPE_DSP        ;DIRECTORY SPEC?
  324.     JE    CHECKI            ;YES, MAY NEED OK
  325.     CMP    AX,TYPE_DRV        ;DRIVE SPEC?
  326.     JNE    NOTDRV            ;NO
  327. CHECKI:
  328.     CMP    BYTE PTR IFLAG,TRUE    ;I FLAG SET?
  329.     JNE    GETOK            ;NO, GET OK
  330.     JMP    NOARGERR        ;ELSE GO AHEAD
  331.     ENDIF
  332. NOTDRV:
  333.     CMP    AX,TYPE_DIR        ;DIRECTORY?
  334.     JNE    NOTDIR
  335.     CMP    BYTE PTR RFLAG,TRUE    ;R FLAG SET?
  336.     JNE    DIRERR            ;NO, ERROR
  337.     JMP    NOARGERR        ;YES, OK
  338. DIRERR:
  339.     ADDR    DX,ARG
  340.     CALL    ERRORMSG        ;SHOW ARGUMENT
  341.     ERROR    3            ;COMPLAIN THAT IT'S A DIRECTORY
  342.     RET
  343. NOTDIR:
  344.     IF    GOOFPROOF
  345.     CMP    AX,TYPE_AFN
  346.     JNE    NOARGERR        ;IF NOT AFN
  347.     CMP    BYTE PTR LEVEL,0
  348.     JG    NOARGERR        ;IF LEVEL>0, DON'T CHECK FOR *.*
  349.     CMP    BYTE PTR IFLAG,TRUE
  350.     JE    NOARGERR        ;DITTO IF I SWITCH SPECIFIED
  351.     CALL    CHECKWILD        ;CHECK FOR *.*
  352.     JNC    NOARGERR        ;IF SOMETHING ELSE
  353. GETOK:
  354. ;    User typed something like *.* or *foo.* or A: or A:\FOO\
  355. ;    In all cases make the end of the path = *.* and ask for 
  356. ;    confirmation.
  357.     ADDR    SI,SPATH
  358.     MOV    WORD PTR FNAME_START, SI
  359. FINDFNAME:
  360.     MOV    AL, BYTE PTR [SI]
  361.     CMP    AL, ':'
  362.     JE    FOUNDPATH
  363.     CMP    AL, '\'
  364.     JE    FOUNDPATH
  365.     CMP    AL, 0
  366.     JE    ENDOFNAME
  367.     INC    SI
  368.     JMP    FINDFNAME
  369. FOUNDPATH:
  370.     INC    SI
  371.     MOV    WORD PTR FNAME_START, SI
  372.     JMP    FINDFNAME
  373. ENDOFNAME:
  374.     MOV    DI, WORD PTR FNAME_START
  375.     MOV    AL, '*'
  376.     STOSB
  377.     MOV    AL, '.'
  378.     STOSB
  379.     MOV    AL, '*'
  380.     STOSB
  381.     XOR    AL, AL
  382.     STOSB
  383.     ADDR    DX,SPATH
  384.     CALL    ERRORMSG        ;SHOW SEARCH PATH
  385.     ERROR    13    
  386.     ERROR    6A            ;USER TYPED *.*, ASK FOR CONFIRMATION
  387.     CALL    GETYORN
  388.     CMP    AL,'Y'
  389.     JE    NOARGERR        ;GO AHEAD IF 'Y' TYPED
  390.     MOV    AL,13            ;SET EXIT CODE
  391.     JMP    EXIT2
  392.     ENDIF
  393. ;******************************************
  394. ; SEE IF ANYTHING MATCHES THE SEARCH SPEC *
  395. ;******************************************
  396. NOARGERR:
  397.         ADDR    DX,SPATH                ;POINT TO SEARCH PATH
  398.         MOV     CX,31H                  ;SET SEARCH ATTRIBUTES
  399.         MOV     AH,FIND_FIRST
  400.         INT     DOS                     ;SEARCH FOR 1ST MATCH
  401.         JNC     GOTONE                  ;OK IF SOMETHING FOUND
  402.         ADDR    DX,ARG
  403.         CALL    ERRORMSG                ;ELSE SHOW ARGUMENT
  404.         ERROR   2                       ;SAY IT DOESN'T EXIST
  405.     RET
  406. ;**************
  407. ; TOP OF LOOP *
  408. ;**************
  409. GOTONE:
  410.         CALL    BUILD_NAME              ;MAKE UNAMBIG. FILE NAME
  411.         JNC     NOSKIP
  412.         JMP     NEXTFILE                ;IF "FILE" IS "." OR ".." 
  413. NOSKIP:
  414.         TEST    [BX].DTA+21,BIT$DIR     ;IS THIS A DIRECTORY?
  415.         JNZ    GOTADIR            ;YES.
  416.     JMP    RMFILE            ;NO, IT'S A FILE
  417. ;*************************************************************
  418. ; IF ARG IS A DIRECTORY, AND R FLAG SET, DELETE ITS CONTENTS *
  419. ;*************************************************************
  420. GOTADIR:
  421.     CMP    BYTE PTR RFLAG,TRUE    ;R FLAG SET?
  422.     JE    RSET            ;YES, OK TO DELETE DIRECTORY
  423.     JMP    NEXTFILE        ;NO, JUST SKIP OVER DIRECTORY
  424. RSET:
  425.     CMP    BYTE PTR IFLAG,TRUE    ;I FLAG SET?
  426.     JNE    INOTSET            ;NO, GO INTO DIRECTORY
  427.     ADDR    DX,FULLNAME
  428.     CALL    ERRORMSG        ;SHOW DIRECTORY NAME
  429.     ERROR    11            ;ASK IF USER WANTS TO ENTER IT
  430.     CALL    GETYORN            ;GET RESPONSE
  431.     CMP    AL,'N'
  432.     JE    NEXTFILE        ;IF N TYPED
  433. INOTSET:
  434.         CMP     WORD PTR LEVEL,MAXLEVEL-1 ;ARE WE AT MAX LEVEL?
  435.         JL      NOTMAX                  ;NO
  436.         ERROR   7                       ;YES, TOO DEEP
  437.     MOV    AL,7            ;SET EXIT CODE
  438.         JMP     EXIT2
  439. NOTMAX:
  440.         COPYPATH FULLNAME,(ARG+RMSTRUCSIZE)  ;COPY DIRECTORY TO ARG AT NEXT LEVEL
  441.         PUSH    BX                      ;SAVE POINTER TO BASE
  442.         INC     WORD PTR LEVEL          ;INCREMENT RECURSION LEVEL
  443.         ADD     WORD PTR RBASE,RMSTRUCSIZE ;ADVANCE BASE POINTER
  444.         CALL    RMIT                    ;REMOVE THE DIRECTORY CONTENTS
  445.         POP     BX                      ;RESTORE BASE POINTER
  446.         DEC     WORD PTR LEVEL           ;DECREMENT RECURSION LEVEL
  447.         SUB     WORD PTR RBASE,RMSTRUCSIZE  ;RESTORE BASE TO PREVIOUS LEVEL
  448.         ADDR    DX,DTA
  449.         MOV     AH,SET_DTA
  450.         INT     DOS                     ;RESET DTA
  451.         JMP     SHORT NEXTFILE          ;DO NEXT FILE
  452. ;**************************
  453. ; FOUND A FILE, REMOVE IT *
  454. ;**************************
  455. RMFILE:
  456.         CMP     BYTE PTR VFLAG,TRUE      ;CHECK VERBOSE FLAG
  457.         JNE     QUIET                   ;IF QUIET MODE
  458.         ADDR    DX,FULLNAME             ;NOT QUIET, SHOW VERBIAGE
  459.         CALL    ERRORMSG
  460.         CALL    CRLF
  461. QUIET:
  462.         CALL    RM_FILE
  463.     JNC    NEXTFILE
  464.     ADDR    DX,FULLNAME        ;IF ERROR, SHOW NAME
  465.     ERROR    5            ;AND ERROR MSG.
  466. ;*****************
  467. ; BOTTOM OF LOOP *
  468. ;*****************
  469. NEXTFILE:
  470.         MOV     AH,FIND_NEXT
  471.         INT     DOS                     ;FIND NEXT MATCH, IF ANY
  472.         JC      NOMORE                  ;IF NONE
  473.         JMP     GOTONE                  ;GOT ONE, BACK TO TOP OF LOOP
  474. ;*************************************************
  475. ; NO MORE FILES, DELETE DIRECTORY (IF NECESSARY) *
  476. ; ************************************************
  477. NOMORE:
  478.     CMP    WORD PTR [BX].PATHTYPE,TYPE_DIR    ;WAS THIS ARG A DIRECTORY?
  479.     JNE    DONE            ;NO, DONE
  480.     CMP    BYTE PTR RFLAG,TRUE    ;RFLAG SET?
  481.     JNE    DONE            ;NO, DONE
  482.     ADDR    DX,ARG            ;POINT TO DIRECTORY NAME
  483.     CMP    BYTE PTR IFLAG,TRUE    ;I FLAG SET?
  484.     JNE    NOI
  485.     CALL    ERRORMSG        ;DISPLAY DIRECTORY NAME
  486.     ERROR    12            ;ASK FOR OK TO DELETE
  487.     CALL    GETYORN            ;GET Y OR N RESPONSE
  488.     CMP    AL,'N'
  489.     JE    DONE            ;IF N, DON'T DELETE IT
  490. NOI:
  491.     ADDR    DX,ARG
  492.     MOV    AH,RMDIR        
  493.     INT    DOS            ;REMOVE DIRECTORY (IT SHOULD BE EMPTY NOW)
  494.     JNC    DONE            ;IF OK
  495.     ADDR    DX,ARG
  496.     CALL    ERRORMSG        ;ELSE SHOW DIRECTORY NAME
  497.     ERROR    5            ;AND ERROR MSG.
  498. DONE:
  499.         RET                             ;ALL DONE
  500. RMIT    ENDP
  501.  
  502. ;**************************************************
  503. ; CHECKWILD = CHECK ARG FOR *.* ERASURE
  504. ; RETURNS 'C' = 1 IF *.* ON WHOLE DIRECTORY OR DRIVE 
  505.  
  506. CHECKWILD PROC    NEAR
  507.     ADDR    SI,ARG            ;GET ARG
  508.     MOV    WORD PTR FNAME_START, SI
  509. FINDFN:                    ;FIND THE FILE NAME PORTION
  510.     CMP    BYTE PTR [SI],0
  511.         JE    GOTEND
  512.     CMP    BYTE PTR [SI],'\'
  513.     JE    PATH_CHAR
  514.     CMP    BYTE PTR [SI],':'
  515.     JE    PATH_CHAR
  516.     INC    SI
  517.     JMP    SHORT FINDFN
  518. PATH_CHAR:
  519.     INC    SI
  520.     CMP    BYTE PTR [SI], 0    ; IF ARG ENDS W. \ OR :
  521.     JE    WIPEOUT            ; TREAT AS WILDCARD
  522.     MOV    WORD PTR FNAME_START, SI
  523.     JMP    SHORT FINDFN
  524. GOTEND:
  525.     MOV    SI, WORD PTR FNAME_START ; GET START OF FILE NAME    
  526.         CMP    BYTE PTR [SI], '*'    ; IS IT STAR?
  527.     JNE    NOTWIPE            ; J/NO
  528. FINDEXT:
  529.     INC    SI
  530.     CMP    BYTE PTR [SI], '.'
  531.     JE    FOUND_EXT
  532.     CMP    BYTE PTR [SI], 0
  533.     JE    NOTWIPE
  534.     JMP    FINDEXT
  535. FOUND_EXT:
  536.     INC    SI
  537.     CMP    BYTE PTR [SI], '*'
  538.     JNE    NOTWIPE
  539. WIPEOUT:
  540.     STC
  541.     RET
  542. NOTWIPE:
  543.     CLC
  544.     RET
  545.  
  546. CHECKWILD ENDP
  547.  
  548.         PAGE +
  549. ;*****************************************************************************
  550. ; THIS ROUTINE TAKES THE INFO ON A FILE IN THE DTA AND USES IT TO GENERATE A
  551. ; FULL, UNAMBIGUOUS FILE NAME BY ADDING THE NECESSARY DIRECTORY PREFIXES TO IT.
  552. ; IT SETS THE CARRY FLAG IF THE "FILE" IS "." OR "..".
  553. ;
  554. BUILD_NAME  PROC  NEAR
  555.         COPYPATH SPREFIX,FULLNAME       ;GET SOURCE PREFIX, COPY TO FULL NAME
  556.         DEC     DI                      ;BACK UP OVER NULL
  557.         ADDR    SI,(DTA+30)             ;POINT TO FILE NAME WE FOUND
  558.         CMP     [SI],BYTE PTR '.'       ;DOES IT START WITH .? -
  559.         JNE     NOTDOT                  ;- NO
  560.         STC                             ;- YES, SET CARRY TO SKIP IT
  561.         RET
  562. NOTDOT:
  563.         CALL    CPYCNT                  ;ADD IT TO SOURCE PREFIX
  564.     CLC                ;CLEAR CARRY
  565.         RET
  566. BUILD_NAME ENDP
  567.  
  568. ;*************************************************************************
  569. ; REMOVE ONE FILE (NAME IS IN FIELD 'FULLNAME' OF THE 'RMSTRUC' POINTED TO
  570. ; BY BX).  RETURNS WITH CARRY SET IF ERROR.
  571. ;
  572. RM_FILE    PROC    NEAR
  573.         CMP     BYTE PTR IFLAG,TRUE      ;IS FLAG SET TO CONFIRM?
  574.         JNE     COK                     ;NO.
  575.         ADDR    DX,FULLNAME
  576.         CALL    ERRORMSG                ;SHOW FILE
  577.         ERROR   4                       ;ASK FOR CONFIRMATION
  578.     CALL    GETYORN            ;GET Y OR N RESPONSE
  579.         CMP     AL,'Y'                  ;IS IT YES?
  580.         JNE     OKEXIT                  ;NO, RETURN W/O ERROR
  581. COK:
  582. TRYAGAIN:
  583.         ADDR    DX,FULLNAME
  584.         MOV     AH,UNLINK
  585.         INT     DOS                     ;UNLINK THAT SUCKER
  586.         JNC     OKEXIT                  ;IF NO PROBLEM
  587.         CMP     AX,5                    ;WAS FILE R/O? (THIS OUGHT TO BE
  588.                                         ; THE ONLY POSSIBLE ERROR)
  589.         JNE     ABEXIT                  ;EXIT IF SOME OTHER ERROR
  590.     CMP    BYTE PTR FFLAG,TRUE    ;CHECK F FLAG
  591.     JE    NOWARN            ;IF SET, DON'T WARN ABOUT R/O FILE
  592.     ADDR    DX,FULLNAME
  593.     CALL    ERRORMSG        ;SHOW FILE NAME
  594.         ERROR   6                       ;R/O FILE, QUERY USER AGAIN
  595.     CALL    GETYORN            ;GET Y OR N RESPONSE
  596.         CMP     AL,'Y'                  ;TEST FOR 'Y' RESPONSE
  597.         JNE     OKEXIT                  ;QUIT (WITH NO ERROR) IF USER SAYS 'N'
  598. NOWARN:
  599.         MOV     CX,0                    ;'Y' TYPED CLEAR ALL ATTRIBUTES
  600.         ADDR    DX,FULLNAME             ;POINT TO FILE NAME
  601.         MOV     AH,CHMOD
  602.         MOV     AL,1                    ;CHANGE ATTRIBUTES
  603.         INT     DOS                     ;TRY MAKING IT R/W
  604.         JMP     TRYAGAIN                ;TRY TO ERASE IT AGAIN
  605. ABEXIT: STC
  606.         RET
  607. OKEXIT: CLC
  608.         RET
  609. RM_FILE    ENDP
  610.  
  611. EXIT2:
  612.         MOV     AH,EXIT
  613.         INT     DOS                     ;EXIT TO DOS
  614.  
  615.         END     ENTRY
  616.  
  617.